package com.cougil.uoc.seghismed.model.ciphed;

import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.JoinTable;
import javax.persistence.Lob;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.hibernate.annotations.CollectionOfElements;
import org.hibernate.annotations.MapKey;
import org.hibernate.annotations.MapKeyManyToMany;

import com.cougil.uoc.seghismed.model.Pacient;
import com.cougil.uoc.seghismed.model.ciphed.MetgeCiphed;
import com.cougil.uoc.seghismed.model.ciphed.VisitaCiphed;

/**
 * Entitat de negoci que representa pròpiament l'Historial d'un Pacient amb la seva informació xifrada
 * @author Ignacio Cougil Jares
 */

public class HistorialCiphed {
	
	private byte[] idCiphed;

	//llista de descriptors de visites xifrada (metges que han visitat el pacientCiphed) 
	private Set<VisitaCiphed> visitesProtegides = new HashSet<VisitaCiphed>();
	
	// llista de metges xifrada amb permís per accedir a l'historial i fins quan
	private Map<MetgeCiphed, Date> metgesAmbAccesProtegit = new HashMap<MetgeCiphed, Date>();
    
	// pacient xifrat
	private PacientCiphed pacientCiphed;
	
	/**
	 * @return Retorna el valor de la propietat idCiphed
	 */
	public byte[] getIdCiphed() {
		return idCiphed;
	}

	/**
	 * @param Estableix idCiphed com a valor de la propietat idCiphed
	 */
	public void setIdCiphed(byte[] idCiphed) {
		this.idCiphed = idCiphed;
	}

	/**
	 * @return Retorna el valor de la propietat visitesProtegides
	 */
	public Set<VisitaCiphed> getVisitesProtegides() {
		return visitesProtegides;
	}

	/**
	 * @param Estableix visitesProtegides com a valor de la propietat visitesProtegides
	 */
	public void setVisitesProtegides(Set<VisitaCiphed> visitesProtegides) {
		this.visitesProtegides = visitesProtegides;
	}

	/**
	 * @return Retorna el valor de la propietat metgesAmbAccesProtegit
	 */
	public Map<MetgeCiphed, Date> getMetgesAmbAccesProtegit() {
		return metgesAmbAccesProtegit;
	}

	/**
	 * @param Estableix metgesAmbAccesProtegit com a valor de la propietat metgesAmbAccesProtegit
	 */
	public void setMetgesAmbAccesProtegit(
			Map<MetgeCiphed, Date> metgesAmbAccesProtegit) {
		this.metgesAmbAccesProtegit = metgesAmbAccesProtegit;
	}
	
	/**
	 * Retorna una col·leció amb el conjunt de metges disponibles associats a l'historial
	 * @return {@link Set<MetgeCiphed>} set amb el conjunt d'elements 
	 * @see java.util.Map#keySet()
	 */
	public Set<MetgeCiphed> getMetges() {
		return metgesAmbAccesProtegit.keySet();
	}
	
	/**
	 * @return Retorna el valor de la propietat pacientCiphed
	 */
	public PacientCiphed getPacientCiphed() {
		return pacientCiphed;
	}

	/**
	 * @param Estableix pacientCiphed com a valor de la propietat pacientCiphed
	 */
	public void setPacientCiphed(PacientCiphed pacientCiphed) {
		this.pacientCiphed = pacientCiphed;
	}

	/**
	 * Afegeix un nou metge més la informació de fins quan tindrà accés a l'historial
	 * @param metge {@link MetgeCiphed} metge a afegir
	 * @param dataLimit {@link Date} data fins la qual tindrà accés el metge
	 * @return {@link Date} anterior data associada al metge o null en cas contrari
	 * @see java.util.Map#put(java.lang.Object, java.lang.Object)
	 */
	public Date putMetge(MetgeCiphed metge, Date dataLimit) {
		return metgesAmbAccesProtegit.put(metge, dataLimit);
	}

	/**
	 * Retorna el nombre de metges associats
	 * @return nombre d'elements
	 * @see java.util.Map#size()
	 */
	public int sizeMetges() {
		return metgesAmbAccesProtegit.size();
	}

	/**
	 * Retorna una col·leció amb el conjunt de dates disponibles associades als metges
	 * @return {@link Collection<Date>} iterador amb el conjunt d'elements 
	 * @see java.util.Map#values()
	 */
	public Collection<Date> getDatesMetges() {
		return metgesAmbAccesProtegit.values();
	}

	/**
	 * Afegeix una visita xifrada nova a la llista
	 * @param e {@link VisitaCiphed} element a afegir
	 * @return true si la llista no contenia previament l'element a afegir
	 * @see java.util.Set#add(java.lang.Object)
	 */
	public boolean addVisita(VisitaCiphed e) {
		return visitesProtegides.add(e);
	}

	/**
	 * Retorna un iterador amb el conjunt de visites xifrades associades
	 * @return {@link Iterator} iterador amb el conjunt d'elements 
	 * @see java.util.Set#iterator()
	 */
	public Iterator<VisitaCiphed> iteratorVisites() {
		return visitesProtegides.iterator();
	}
	
	/**
	 * Retorna el nombre de visites associades
	 * @return nombre d'elements
	 * @see java.util.Set#size()
	 */
	public int sizeVisites() {
		return visitesProtegides.size();
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(final Object other) {
		if (!(other instanceof HistorialCiphed))
			return false;
		HistorialCiphed castOther = (HistorialCiphed) other;
		return new EqualsBuilder().append(idCiphed, castOther.idCiphed).isEquals();
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		return new HashCodeBuilder().append(idCiphed).toHashCode();
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
				.appendSuper(super.toString())
				.append("idCiphed", idCiphed)
				.append("visitesProtegides", visitesProtegides)
				.append("metgesAmbAccesProtegit", metgesAmbAccesProtegit)
				.toString();
	}

	
	
}
